<style src="./index.scss" lang="scss" scoped></style>
<template>
    <div class="ask-excel-box">
        <div class="ask-excel__toolbar">
            <el-button @click="move('down')">下移</el-button>
            <el-button @click="move('up')">上移</el-button>
            <el-button @click="move('left')">左移</el-button>
            <el-button @click="move('right')">右移</el-button>
            {{scrollHeight}}{{verBarStyle}}
        </div>
        <div class="ask-excel__body">
            <div class="ask-excel__container" ref="askExcelContainerRef"></div>
            <div class="ask-excel__scrollbar">
                <div class="ask-excel__scrollbar-hor" v-if="scrollWidth">
                    <div
                        @mousedown="handleMousedown($event, 'hor')"
                        class="ask-excel__scrollbar-hor-board"
                        :class="{active: scrollMove.direction === 'hor'}"
                        :style="horBarStyle"></div>
                </div>
                <div class="ask-excel__scrollbar-ver" v-if="scrollHeight">
                    <div
                        @mousedown="handleMousedown($event, 'ver')"
                        :class="{active: scrollMove.direction === 'ver'}"
                        class="ask-excel__scrollbar-ver-board"
                        :style="verBarStyle"></div>
                </div>
            </div>
            <div class="ask-excel__editor-box">
                <div class="ask-excel__editor-span" :style="editorSpanStyle"></div>
            </div>
            <div class="ask-excel__editor-box-content" v-show="editorContentBoxDisplay">
                <div class="ask-excel__editor-span"
                    :style="editorSpanContenteditableStyle"
                    ref="editorContentBoxRef"
                    @blur="handleEditorContentBoxBlur"
                    contenteditable>
                    {{editorItemValue}}
                </div>
            </div>
        </div>
    </div>
</template>

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import { AskExcel } from "./src";
import { ObserverEvent, throttle, merge } from "@/utils";
@Component
export default class AskExcelComponent extends Vue {
    tdData: any[] = [];
    thData: any[] = [];
    excel: any = null;
    maxScroll = 4000;
    scrollMove: {
        direction: string;
        x: number;
        y: number;
    } = {
        direction: "",
        x: 0,
        y: 0
    };

    editorSpanStyle: any = {};
    editorSpanContenteditableStyle: any = {};
    editorContentBoxDisplay = false;
    editorItem: any = {};
    editorItemValue: any = "";

    get scrollWidth() {
        let value = 0;
        if (this.excel && this.excel.instance) {
            value = this.excel.instance.scrollWidth;
        }
        return value;
    }

    get scrollHeight() {
        let value = 0;
        if (this.excel && this.excel.instance) {
            value = this.excel.instance.scrollHeight;
        }
        return value;
    }

    get scrollTop() {
        let value = 0;
        if (this.excel && this.excel.instance) {
            value = this.excel.instance.scrollTop;
        }
        return value;
    }

    get scrollLeft() {
        let value = 0;
        if (this.excel && this.excel.instance) {
            value = this.excel.instance.scrollLeft;
        }
        return value;
    }

    get horBarStyle() {
        let value = 0;
        if (this.excel && this.excel.instance) {
            value = this.excel.instance.width;
        }
        const sourceHeight = this.scrollWidth + value;
        const maxScroll = this.maxScroll;
        const scale = sourceHeight > maxScroll ? value / maxScroll : value / sourceHeight;
        const barWidth = scale * value;
        const scrollH = value - barWidth;
        const barTransform = scrollH * this.scrollLeft / this.scrollWidth;
        return {
            _scrollH: scrollH,
            width: barWidth + 'px',
            transform: 'translateX(' + barTransform + 'px)'
        };
    }

    get verBarStyle() {
        let value = 0;
        if (this.excel && this.excel.instance) {
            value = this.excel.instance.height;
        }
        const sourceHeight = this.scrollHeight + value;
        const maxScroll = this.maxScroll;
        const scale = sourceHeight > maxScroll ? value / maxScroll : value / sourceHeight;
        const barHeight = scale * value;
        const scrollH = value - barHeight;
        const barTransform = scrollH * this.scrollTop / this.scrollHeight;
        return {
            _scrollH: scrollH,
            height: barHeight + 'px',
            transform: 'translateY(' + barTransform + 'px)'
        };
    }

    mounted() {
        this.initScrollEvent();
        for (let i = 0; i < 10; i += 1) {
            this.thData.push({
                // style?: StyleMeta;
                // position: PositionMeta;
                value: i + "值", // 值
                placeholder: "提示文字"
            });
        }
        for (let i = 0; i < 200; i += 1) {
            const _td = [];
            for (let j = 0; j < this.thData.length; j += 1) {
                _td.push({
                    // style: StyleMeta;
                    // position: PositionMeta;
                    value: i + "-" + j + "值测试大小的", // 值
                    placeholder: "提示文字",
                    style: {
                        height: 50
                    },
                    // input | date | select | cascader | img | location
                    type: "input" // 渲染类型
                });
            }
            this.tdData.push(_td);
        }
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        const instance = this.excel = new AskExcel({
            el: this.$refs.askExcelContainerRef,
            thData: this.thData,
            tdData: this.tdData,
            on: {
                click: (e: any, item: any) => {
                    this.handleItemClick(e, item);
                },
                dblclick: (e: any, item: any) => {
                    this.handleItemDblclickClick(e, item);
                }
            }
        });
        this.$on("hook:beforeDestroy", () => {
            instance.destroy();
        });
        // console.log("???", instance);
    }

    handleItemClick(e: any, item: any) {
        if (!item.particle) return;
        const {
            position: { x, y },
            style: { width, color, font, bgColor },
            value
        } = item.particle;
        this.editorItem = merge(true, {}, item);
        const _style = {
            width: width + "px",
            height: item.height + "px",
            color: color,
            font: font,
            transform: "translate(" + x + "px," + y + "px)"
        };
        this.editorSpanStyle = _style;
        this.editorSpanContenteditableStyle = merge(true, {}, _style);
        this.editorSpanContenteditableStyle.backgroundColor = bgColor || "#fff";
        this.editorItemValue = value;
    }

    handleEditorContentBoxBlur() {
        this.editorContentBoxDisplay = false;
        this.excel.updateCurrentItem("288");
    }

    handleItemDblclickClick(e: any, item: any) {
        this.editorContentBoxDisplay = Boolean(item.particle);
        if (this.editorContentBoxDisplay) {
            this.$nextTick(() => {
                this._autoFocus(this.$refs.editorContentBoxRef);
            });
        }
    }

    _autoFocus(el: any) {
        const range = document.createRange();
        range.selectNodeContents(el);
        range.collapse(false);
        const sel: any = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    }

    move(type: string) {
        const { scrollLeft, scrollTop, scrollWidth, scrollHeight } = this.excel.instance;
        let x = scrollLeft;
        let y = scrollTop;
        if (type === 'down') {
            y = Math.min(scrollHeight, y + 10);
        }
        if (type === 'up') {
            y = Math.max(0, y - 10);
        }
        if (type === 'right') {
            x = Math.min(scrollWidth, x + 10);
        }
        if (type === 'left') {
            x = Math.max(0, x - 10);
        }
        this.excel.scroll(x, y);
    }

    // handleTouchStart() {
    //     // const { sourceIndex } = this.data.drag;
    //     // console.log("handleTouchStart", e);
    //     // if (sourceIndex === null) {
    //     //     return;
    //     // }
    // }

    // handleTouchMove(payload: any) {
    //     const event = payload.event;
    //     const { sourceIndex } = this.data.drag;
    //     if (sourceIndex === null) {
    //         return 10;
    //     }
    //     const { clientX, clientY } = event.touches[0] || {};
    //     const {
    //         startX, startY, top, left, bounds
    //     } = this.data.drag;
    //     const calcX = clientX;
    //     const calcY = clientY;
    //     const move = [left + calcX - startX, top + calcY - startY];
    //     if (move[0] <= 0) {
    //         move[0] = 0;
    //     }
    //     if (move[1] <= 0) {
    //         move[1] = 0;
    //     }
    //     if (move[0] >= bounds[0]) {
    //         move[0] = bounds[0];
    //     }
    //     if (move[1] >= bounds[1]) {
    //         move[1] = bounds[1];
    //     }
    //     this.setData({
    //         "drag.move": move
    //     });
    //     this.calcDragPositionAndSet();
    //     return 20;
    // }

    // handleTouchEnd() {
    //     const { sourceIndex } = this.data.drag;
    //     if (sourceIndex === null) {
    //         return;
    //     }
    //     this.dragEnd();
    //     // console.log("handleTouchEnd", e);
    // }

    // handleTouchCancel() {
    //     const { sourceIndex } = this.data.drag;
    //     if (sourceIndex === null) {
    //         return;
    //     }
    //     this.dragEnd();
    //     // console.log("handleTouchCancel", e);
    // }

    handleMousedown(e: any, type: any) {
        this.scrollMove = {
            direction: type,
            x: e.screenX,
            y: e.screenY
        };
    }

    handleMousemove(e: any) {
        if (!this.scrollMove.direction) {
            return;
        }
        const { screenX, screenY } = e;
        const { direction, x, y } = this.scrollMove;
        const { scrollLeft, scrollTop } = this.excel.instance;
        const k = 1;
        if (direction === 'ver') {
            const scrollH = this.verBarStyle._scrollH;
            const diff = (screenY - y) * this.scrollHeight / scrollH * k;
            this.excel.scroll(scrollLeft, scrollTop + diff);
        }
        if (direction === 'hor') {
            const scrollH = this.horBarStyle._scrollH;
            const diff = (screenX - x) * this.scrollWidth / scrollH * k;
            this.excel.scroll(scrollLeft + diff, scrollTop);
        }
        this.scrollMove.x = screenX;
        this.scrollMove.y = screenY;
    }

    handleMouseup() {
        this.scrollMove.direction = "";
        this.scrollMove.x = 0;
        this.scrollMove.y = 0;
    }

    initScrollEvent() {
        const mousemoveEvent = ObserverEvent(window, "mousemove", throttle(this.handleMousemove, 16));
        const mouseupEvent = ObserverEvent(window, "mouseup", this.handleMouseup);
        this.$on("hook:beforeDestroy", () => {
            mousemoveEvent.destroy();
            mouseupEvent.destroy();
        });
    }
}
</script>
